<html><!-- Created using the cpp_pretty_printer from the dlib C++ library.  See http://dlib.net for updates. --><head><title>dlib C++ Library - matrix_la.h</title></head><body bgcolor='white'><pre>
<font color='#009900'>// Copyright (C) 2009  Davis E. King (davis@dlib.net)
</font><font color='#009900'>// License: Boost Software License   See LICENSE.txt for the full license.
</font><font color='#0000FF'>#ifndef</font> DLIB_MATRIx_LA_FUNCTS_
<font color='#0000FF'>#define</font> DLIB_MATRIx_LA_FUNCTS_ 

<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_la_abstract.h.html'>matrix_la_abstract.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_utilities.h.html'>matrix_utilities.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../sparse_vector.h.html'>../sparse_vector.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='../optimization/optimization_line_search.h.html'>../optimization/optimization_line_search.h</a>"

<font color='#009900'>// The 4 decomposition objects described in the matrix_la_abstract.h file are
</font><font color='#009900'>// actually implemented in the following 4 files.  
</font><font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_lu.h.html'>matrix_lu.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_qr.h.html'>matrix_qr.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_cholesky.h.html'>matrix_cholesky.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='matrix_eigenvalue.h.html'>matrix_eigenvalue.h</a>"

<font color='#0000FF'>#ifdef</font> DLIB_USE_LAPACK
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='lapack/potrf.h.html'>lapack/potrf.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='lapack/gesdd.h.html'>lapack/gesdd.h</a>"
<font color='#0000FF'>#include</font> "<a style='text-decoration:none' href='lapack/gesvd.h.html'>lapack/gesvd.h</a>"
<font color='#0000FF'>#endif</font>

<font color='#0000FF'>namespace</font> dlib
<b>{</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>enum</font> <b><a name='svd_u_mode'></a>svd_u_mode</b>
    <b>{</b>
        SVD_NO_U,
        SVD_SKINNY_U,
        SVD_FULL_U
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> qN, <font color='#0000FF'><u>long</u></font> qX,
        <font color='#0000FF'><u>long</u></font> uM, <font color='#0000FF'><u>long</u></font> uN,
        <font color='#0000FF'><u>long</u></font> vM, <font color='#0000FF'><u>long</u></font> vN,
        <font color='#0000FF'>typename</font> MM1,
        <font color='#0000FF'>typename</font> MM2,
        <font color='#0000FF'>typename</font> MM3,
        <font color='#0000FF'>typename</font> L1
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>long</u></font> <b><a name='svd4'></a>svd4</b> <font face='Lucida Console'>(</font>
        svd_u_mode u_mode, 
        <font color='#0000FF'><u>bool</u></font> withv, 
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> a,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,uM,uN,MM1,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u, 
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,qN,qX,MM2,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> q, 
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,vM,vN,MM3,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#009900'>/*  
            Singular value decomposition. Translated to 'C' from the
            original Algol code in "Handbook for Automatic Computation,
            vol. II, Linear Algebra", Springer-Verlag.  Note that this
            published algorithm is considered to be the best and numerically
            stable approach to computing the real-valued svd and is referenced
            repeatedly in ieee journal papers, etc where the svd is used.

            This is almost an exact translation from the original, except that
            an iteration counter is added to prevent stalls. This corresponds
            to similar changes in other translations.

            Returns an error code = 0, if no errors and 'k' if a failure to
            converge at the 'kth' singular value.

            USAGE: given the singular value decomposition a = u * diagm(q) * trans(v) for an m*n 
                    matrix a with m &gt;= n ...  
                    After the svd call u is an m x m matrix which is columnwise 
                    orthogonal. q will be an n element vector consisting of singular values 
                    and v an n x n orthogonal matrix. eps and tol are tolerance constants. 
                    Suitable values are eps=1e-16 and tol=(1e-300)/eps if T == double. 

                    If u_mode == SVD_NO_U then u won't be computed and similarly if withv == false
                    then v won't be computed.  If u_mode == SVD_SKINNY_U then u will be m x n instead of m x m.
        */</font>


        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>a.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix_exp svd4()</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou have given an invalidly sized matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\ta.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> a.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\ta.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;


        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> EXP::type T;

<font color='#0000FF'>#ifdef</font> DLIB_USE_LAPACK
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM1,L1<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>temp</font><font face='Lucida Console'>(</font>a<font face='Lucida Console'>)</font>, vtemp;

        <font color='#0000FF'><u>char</u></font> jobu <font color='#5555FF'>=</font> '<font color='#FF0000'>A</font>';
        <font color='#0000FF'><u>char</u></font> jobvt <font color='#5555FF'>=</font> '<font color='#FF0000'>A</font>';
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>=</font><font color='#5555FF'>=</font> SVD_NO_U<font face='Lucida Console'>)</font>
            jobu <font color='#5555FF'>=</font> '<font color='#FF0000'>N</font>';
        <font color='#0000FF'>else</font> <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>=</font><font color='#5555FF'>=</font> SVD_SKINNY_U<font face='Lucida Console'>)</font>
            jobu <font color='#5555FF'>=</font> '<font color='#FF0000'>S</font>';
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
            jobvt <font color='#5555FF'>=</font> '<font color='#FF0000'>N</font>';

        <font color='#0000FF'><u>int</u></font> info;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>jobu <font color='#5555FF'>=</font><font color='#5555FF'>=</font> jobvt<font face='Lucida Console'>)</font>
        <b>{</b>
            info <font color='#5555FF'>=</font> lapack::<font color='#BB00BB'>gesdd</font><font face='Lucida Console'>(</font>jobu, temp, q, u, vtemp<font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            info <font color='#5555FF'>=</font> lapack::<font color='#BB00BB'>gesvd</font><font face='Lucida Console'>(</font>jobu, jobvt, temp, q, u, vtemp<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#009900'>// pad q with zeros if it isn't the length we want
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>q.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            q <font color='#5555FF'>=</font> <font color='#BB00BB'>join_cols</font><font face='Lucida Console'>(</font>q, zeros_matrix<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>q.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv<font face='Lucida Console'>)</font>
            v <font color='#5555FF'>=</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>vtemp<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>return</font> info;
<font color='#0000FF'>#else</font>
        <font color='#0000FF'>using</font> std::abs;
        <font color='#0000FF'>using</font> std::sqrt;

        T eps <font color='#5555FF'>=</font> std::numeric_limits<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>epsilon</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        T tol <font color='#5555FF'>=</font> std::numeric_limits<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>/</font>eps;

        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> m <font color='#5555FF'>=</font> a.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> n <font color='#5555FF'>=</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'><u>long</u></font> i, j, k, l <font color='#5555FF'>=</font> <font color='#979000'>0</font>, l1, iter, retval;
        T c, f, g, h, s, x, y, z;

        matrix<font color='#5555FF'>&lt;</font>T,qN,<font color='#979000'>1</font>,MM2<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>n,<font color='#979000'>1</font><font face='Lucida Console'>)</font>; 
        q.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>n,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>=</font><font color='#5555FF'>=</font> SVD_FULL_U<font face='Lucida Console'>)</font>
            u.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>m,m<font face='Lucida Console'>)</font>;
        <font color='#0000FF'>else</font>
            u.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>m,n<font face='Lucida Console'>)</font>;
        retval <font color='#5555FF'>=</font> <font color='#979000'>0</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv<font face='Lucida Console'>)</font>
        <b>{</b>
            v.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>n,n<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#009900'>/* Copy 'a' to 'u' */</font>    
        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font><font color='#979000'>0</font>; i<font color='#5555FF'>&lt;</font>m; i<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font><font color='#979000'>0</font>; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font>;
        <b>}</b>

        <font color='#009900'>/* Householder's reduction to bidiagonal form. */</font>
        g <font color='#5555FF'>=</font> x <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;    
        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font><font color='#979000'>0</font>; i<font color='#5555FF'>&lt;</font>n; i<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
        <b>{</b>
            <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> g;
            s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
            l <font color='#5555FF'>=</font> i <font color='#5555FF'>+</font> <font color='#979000'>1</font>;

            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>i; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>s <font color='#5555FF'>&lt;</font> tol<font face='Lucida Console'>)</font>
                g <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
            <font color='#0000FF'>else</font> 
            <b>{</b>
                f <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font>;
                g <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>f <font color='#5555FF'>&lt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font> ? <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>s<font face='Lucida Console'>)</font> : <font color='#5555FF'>-</font><font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>s<font face='Lucida Console'>)</font>;
                h <font color='#5555FF'>=</font> f <font color='#5555FF'>*</font> g <font color='#5555FF'>-</font> s;
                <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> f <font color='#5555FF'>-</font> g;

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                <b>{</b>
                    s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>i; k<font color='#5555FF'>&lt;</font>m; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,i<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                    f <font color='#5555FF'>=</font> s <font color='#5555FF'>/</font> h;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>i; k<font color='#5555FF'>&lt;</font>m; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>f <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <b>}</b> <font color='#009900'>/* end j */</font>
            <b>}</b> <font color='#009900'>/* end s */</font>

            <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> g;
            s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>s <font color='#5555FF'>&lt;</font> tol<font face='Lucida Console'>)</font>
                g <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
            <font color='#0000FF'>else</font> 
            <b>{</b>
                f <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                g <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>f <font color='#5555FF'>&lt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font> ? <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>s<font face='Lucida Console'>)</font> : <font color='#5555FF'>-</font><font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>s<font face='Lucida Console'>)</font>;
                h <font color='#5555FF'>=</font> f <font color='#5555FF'>*</font> g <font color='#5555FF'>-</font> s;
                <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> f <font color='#5555FF'>-</font> g;

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>j<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>/</font> h;

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                <b>{</b>
                    s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>l; k<font color='#5555FF'>&lt;</font>n; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                        s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,k<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,k<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>l; k<font color='#5555FF'>&lt;</font>n; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,k<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>s <font color='#5555FF'>*</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <b>}</b> <font color='#009900'>/* end j */</font>
            <b>}</b> <font color='#009900'>/* end s */</font>

            y <font color='#5555FF'>=</font> <font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font><font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> <font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font><font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;                         
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>y <font color='#5555FF'>&gt;</font> x<font face='Lucida Console'>)</font>
                x <font color='#5555FF'>=</font> y;
        <b>}</b> <font color='#009900'>/* end i */</font>

        <font color='#009900'>/* accumulation of right-hand transformations */</font>
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv<font face='Lucida Console'>)</font> 
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font>n<font color='#5555FF'>-</font><font color='#979000'>1</font>; i<font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font><font color='#979000'>0</font>; i<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>g <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0.0</font><font face='Lucida Console'>)</font> 
                <b>{</b>
                    h <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> g;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font><font color='#5555FF'>/</font>h;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <b>{</b>
                        s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>l; k<font color='#5555FF'>&lt;</font>n; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                            s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,k<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>l; k<font color='#5555FF'>&lt;</font>n; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                            <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>s <font color='#5555FF'>*</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>k,i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    <b>}</b> <font color='#009900'>/* end j */</font>
                <b>}</b> <font color='#009900'>/* end g */</font>

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                    <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1.0</font>;
                g <font color='#5555FF'>=</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;
                l <font color='#5555FF'>=</font> i;
            <b>}</b> <font color='#009900'>/* end i */</font>
        <b>}</b> <font color='#009900'>/* end withv, parens added for clarity */</font>

        <font color='#009900'>/* accumulation of left-hand transformations */</font>
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>!</font><font color='#5555FF'>=</font> SVD_NO_U<font face='Lucida Console'>)</font> 
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font>n; i<font color='#5555FF'>&lt;</font>u.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; i<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>n;j<font color='#5555FF'>&lt;</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                    <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>i <font color='#5555FF'>&lt;</font> u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1.0</font>;
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>!</font><font color='#5555FF'>=</font> SVD_NO_U<font face='Lucida Console'>)</font> 
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font>n<font color='#5555FF'>-</font><font color='#979000'>1</font>; i<font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font><font color='#979000'>0</font>; i<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                l <font color='#5555FF'>=</font> i <font color='#5555FF'>+</font> <font color='#979000'>1</font>;
                g <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;

                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>  
                    <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,j<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>g <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0.0</font><font face='Lucida Console'>)</font> 
                <b>{</b>
                    h <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> g;

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>l; j<font color='#5555FF'>&lt;</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <b>{</b> 
                        s <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;

                        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>l; k<font color='#5555FF'>&lt;</font>m; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                            s <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,i<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                        f <font color='#5555FF'>=</font> s <font color='#5555FF'>/</font> h;

                        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>i; k<font color='#5555FF'>&lt;</font>m; k<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                            <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,j<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>f <font color='#5555FF'>*</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>k,i<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    <b>}</b> <font color='#009900'>/* end j */</font>

                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>i; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>/</font><font color='#5555FF'>=</font> g;
                <b>}</b> <font color='#009900'>/* end g */</font>
                <font color='#0000FF'>else</font> 
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font>i; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
                <b>}</b>

                <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>i,i<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#979000'>1.0</font>;
            <b>}</b> <font color='#009900'>/* end i*/</font>
        <b>}</b> 

        <font color='#009900'>/* diagonalization of the bidiagonal form */</font>
        eps <font color='#5555FF'>*</font><font color='#5555FF'>=</font> x;

        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>k<font color='#5555FF'>=</font>n<font color='#5555FF'>-</font><font color='#979000'>1</font>; k<font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font><font color='#979000'>0</font>; k<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> 
        <b>{</b>
            iter <font color='#5555FF'>=</font> <font color='#979000'>0</font>;

test_f_splitting:

            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>l<font color='#5555FF'>=</font>k; l<font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font><font color='#979000'>0</font>; l<font color='#5555FF'>-</font><font color='#5555FF'>-</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font><font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>l<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> eps<font face='Lucida Console'>)</font> 
                    <font color='#0000FF'>goto</font> test_f_convergence;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font><font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>l<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> eps<font face='Lucida Console'>)</font> 
                    <font color='#0000FF'>goto</font> cancellation;
            <b>}</b> <font color='#009900'>/* end l */</font>

            <font color='#009900'>/* cancellation of e(l) if l &gt; 0 */</font>

cancellation:

            c <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
            s <font color='#5555FF'>=</font> <font color='#979000'>1.0</font>;
            l1 <font color='#5555FF'>=</font> l <font color='#5555FF'>-</font> <font color='#979000'>1</font>;

            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font>l; i<font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font>k; i<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                f <font color='#5555FF'>=</font> s <font color='#5555FF'>*</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font><font color='#5555FF'>=</font> c;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font>f<font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> eps<font face='Lucida Console'>)</font> 
                    <font color='#0000FF'>goto</font> test_f_convergence;

                g <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;
                h <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>f<font color='#5555FF'>*</font>f <font color='#5555FF'>+</font> g<font color='#5555FF'>*</font>g<font face='Lucida Console'>)</font>;
                c <font color='#5555FF'>=</font> g <font color='#5555FF'>/</font> h;
                s <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>f <font color='#5555FF'>/</font> h;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>!</font><font color='#5555FF'>=</font> SVD_NO_U<font face='Lucida Console'>)</font> 
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font><font color='#979000'>0</font>; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <b>{</b>
                        y <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,l1<font face='Lucida Console'>)</font>;
                        z <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font>;
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,l1<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> y <font color='#5555FF'>*</font> c <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> s;
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>y <font color='#5555FF'>*</font> s <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> c;
                    <b>}</b> <font color='#009900'>/* end j */</font>
                <b>}</b> 
            <b>}</b> <font color='#009900'>/* end i */</font>

test_f_convergence:

            z <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>l <font color='#5555FF'>=</font><font color='#5555FF'>=</font> k<font face='Lucida Console'>)</font> 
                <font color='#0000FF'>goto</font> convergence;

            <font color='#009900'>/* shift from bottom 2x2 minor */</font>
            iter<font color='#5555FF'>+</font><font color='#5555FF'>+</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>iter <font color='#5555FF'>&gt;</font> <font color='#979000'>300</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                retval <font color='#5555FF'>=</font> k;
                <font color='#0000FF'>break</font>;
            <b>}</b>
            x <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>l<font face='Lucida Console'>)</font>;
            y <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>k<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            g <font color='#5555FF'>=</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>k<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            h <font color='#5555FF'>=</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font>;
            f <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>y <font color='#5555FF'>-</font> z<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font face='Lucida Console'>(</font>y <font color='#5555FF'>+</font> z<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> <font face='Lucida Console'>(</font>g <font color='#5555FF'>-</font> h<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font face='Lucida Console'>(</font>g <font color='#5555FF'>+</font> h<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>/</font> <font face='Lucida Console'>(</font><font color='#979000'>2</font> <font color='#5555FF'>*</font> h <font color='#5555FF'>*</font> y<font face='Lucida Console'>)</font>;
            g <font color='#5555FF'>=</font> <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>f <font color='#5555FF'>*</font> f <font color='#5555FF'>+</font> <font color='#979000'>1.0</font><font face='Lucida Console'>)</font>;
            f <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>x <font color='#5555FF'>-</font> z<font face='Lucida Console'>)</font> <font color='#5555FF'>*</font> <font face='Lucida Console'>(</font>x <font color='#5555FF'>+</font> z<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font> h <font color='#5555FF'>*</font> <font face='Lucida Console'>(</font>y <font color='#5555FF'>/</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>f <font color='#5555FF'>&lt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>?<font face='Lucida Console'>(</font>f <font color='#5555FF'>-</font> g<font face='Lucida Console'>)</font> : <font face='Lucida Console'>(</font>f <font color='#5555FF'>+</font> g<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> h<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>/</font> x;

            <font color='#009900'>/* next QR transformation */</font>
            c <font color='#5555FF'>=</font> s <font color='#5555FF'>=</font> <font color='#979000'>1.0</font>;

            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i<font color='#5555FF'>=</font>l<font color='#5555FF'>+</font><font color='#979000'>1</font>; i<font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font>k; i<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                g <font color='#5555FF'>=</font> <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;
                y <font color='#5555FF'>=</font> <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font>;
                h <font color='#5555FF'>=</font> s <font color='#5555FF'>*</font> g;
                g <font color='#5555FF'>*</font><font color='#5555FF'>=</font> c;
                <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> z <font color='#5555FF'>=</font> <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>f <font color='#5555FF'>*</font> f <font color='#5555FF'>+</font> h <font color='#5555FF'>*</font> h<font face='Lucida Console'>)</font>;
                c <font color='#5555FF'>=</font> f <font color='#5555FF'>/</font> z;
                s <font color='#5555FF'>=</font> h <font color='#5555FF'>/</font> z;
                f <font color='#5555FF'>=</font> x <font color='#5555FF'>*</font> c <font color='#5555FF'>+</font> g <font color='#5555FF'>*</font> s;
                g <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>x <font color='#5555FF'>*</font> s <font color='#5555FF'>+</font> g <font color='#5555FF'>*</font> c;
                h <font color='#5555FF'>=</font> y <font color='#5555FF'>*</font> s;
                y <font color='#5555FF'>*</font><font color='#5555FF'>=</font> c;

                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv<font face='Lucida Console'>)</font> 
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font><font color='#979000'>0</font>;j<font color='#5555FF'>&lt;</font>n;j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <b>{</b>
                        x <font color='#5555FF'>=</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                        z <font color='#5555FF'>=</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font>;
                        <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> x <font color='#5555FF'>*</font> c <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> s;
                        <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>x <font color='#5555FF'>*</font> s <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> c;
                    <b>}</b> <font color='#009900'>/* end j */</font>
                <b>}</b> <font color='#009900'>/* end withv, parens added for clarity */</font>

                <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> z <font color='#5555FF'>=</font> <font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>f <font color='#5555FF'>*</font> f <font color='#5555FF'>+</font> h <font color='#5555FF'>*</font> h<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>z <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                <b>{</b>
                    c <font color='#5555FF'>=</font> f <font color='#5555FF'>/</font> z;
                    s <font color='#5555FF'>=</font> h <font color='#5555FF'>/</font> z;
                <b>}</b>
                f <font color='#5555FF'>=</font> c <font color='#5555FF'>*</font> g <font color='#5555FF'>+</font> s <font color='#5555FF'>*</font> y;
                x <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>s <font color='#5555FF'>*</font> g <font color='#5555FF'>+</font> c <font color='#5555FF'>*</font> y;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u_mode <font color='#5555FF'>!</font><font color='#5555FF'>=</font> SVD_NO_U<font face='Lucida Console'>)</font> 
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font><font color='#979000'>0</font>; j<font color='#5555FF'>&lt;</font>m; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font> 
                    <b>{</b>
                        y <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                        z <font color='#5555FF'>=</font> <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font>;
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> y <font color='#5555FF'>*</font> c <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> s;
                        <font color='#BB00BB'>u</font><font face='Lucida Console'>(</font>j,i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>y <font color='#5555FF'>*</font> s <font color='#5555FF'>+</font> z <font color='#5555FF'>*</font> c;
                    <b>}</b> <font color='#009900'>/* end j */</font>
                <b>}</b> 
            <b>}</b> <font color='#009900'>/* end i */</font>

            <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>l<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>0.0</font>;
            <font color='#BB00BB'>e</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> f;
            <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> x;

            <font color='#0000FF'>goto</font> test_f_splitting;

convergence:

            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>z <font color='#5555FF'>&lt;</font> <font color='#979000'>0.0</font><font face='Lucida Console'>)</font> 
            <b>{</b>
                <font color='#009900'>/* q(k) is made non-negative */</font>
                <font color='#BB00BB'>q</font><font face='Lucida Console'>(</font>k<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font>z;
                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withv<font face='Lucida Console'>)</font> 
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>j<font color='#5555FF'>=</font><font color='#979000'>0</font>; j<font color='#5555FF'>&lt;</font>n; j<font color='#5555FF'>+</font><font color='#5555FF'>+</font><font face='Lucida Console'>)</font>
                        <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,k<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>v</font><font face='Lucida Console'>(</font>j,k<font face='Lucida Console'>)</font>;
                <b>}</b> <font color='#009900'>/* end withv, parens added for clarity */</font>
            <b>}</b> <font color='#009900'>/* end z */</font>
        <b>}</b> <font color='#009900'>/* end k */</font>

        <font color='#0000FF'>return</font> retval;
<font color='#0000FF'>#endif</font>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> qN, <font color='#0000FF'><u>long</u></font> qX,
        <font color='#0000FF'><u>long</u></font> uM, 
        <font color='#0000FF'><u>long</u></font> vN, 
        <font color='#0000FF'>typename</font> MM1,
        <font color='#0000FF'>typename</font> MM2,
        <font color='#0000FF'>typename</font> MM3,
        <font color='#0000FF'>typename</font> L1
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>long</u></font> <b><a name='svd2'></a>svd2</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'><u>bool</u></font> withu, 
        <font color='#0000FF'><u>bool</u></font> withv, 
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> a,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,uM,uM,MM1,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u, 
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,qN,qX,MM2,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> q, 
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,vN,vN,MM3,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NR <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NC <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC;

        <font color='#009900'>// make sure the output matrices have valid dimensions if they are statically dimensioned
</font>        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>qX <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> qX <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> uM <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> uM<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> vN <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> vN<font face='Lucida Console'>)</font>;

        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>a.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix_exp svd4()</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou have given an invalidly sized matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\ta.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> a.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\ta.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> a.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>withu<font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> <font color='#BB00BB'>svd4</font><font face='Lucida Console'>(</font>SVD_FULL_U, withv, a,u,q,v<font face='Lucida Console'>)</font>;
        <font color='#0000FF'>else</font>
            <font color='#0000FF'>return</font> <font color='#BB00BB'>svd4</font><font face='Lucida Console'>(</font>SVD_NO_U, withv, a,u,q,v<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> T,
        <font color='#0000FF'><u>long</u></font> NR,
        <font color='#0000FF'><u>long</u></font> NC,
        <font color='#0000FF'>typename</font> MM,
        <font color='#0000FF'>typename</font> L
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>void</u></font> <b><a name='orthogonalize'></a>orthogonalize</b> <font face='Lucida Console'>(</font>
        matrix<font color='#5555FF'>&lt;</font>T,NR,NC,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font>
    <b>{</b>
        qr_decomposition<font color='#5555FF'>&lt;</font>matrix<font color='#5555FF'>&lt;</font>T,NR,NC,MM,L<font color='#5555FF'>&gt;</font> <font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>.<font color='#BB00BB'>get_q</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> T,
        <font color='#0000FF'><u>long</u></font> Anr, <font color='#0000FF'><u>long</u></font> Anc,
        <font color='#0000FF'>typename</font> MM,
        <font color='#0000FF'>typename</font> L
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>void</u></font> <b><a name='find_matrix_range'></a>find_matrix_range</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font>T,Anr,Anc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> l,
        matrix<font color='#5555FF'>&lt;</font>T,Anr,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> Q,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> q 
    <font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        requires
            - A.nr() &gt;= l
        ensures
            - #Q.nr() == A.nr() 
            - #Q.nc() == l
            - #Q == an orthonormal matrix whose range approximates the range of the
              matrix A.  
            - This function implements the randomized subspace iteration defined 
              in the algorithm 4.4 box of the paper: 
                Finding Structure with Randomness: Probabilistic Algorithms for
                Constructing Approximate Matrix Decompositions by Halko et al.
            - q defines the number of extra subspace iterations this algorithm will
              perform.  Often q == 0 is fine, but performing more iterations can lead to a
              more accurate approximation of the range of A if A has slowly decaying
              singular values.  In these cases, using a q of 1 or 2 is good.
    !*/</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font><font face='Lucida Console'>)</font>l, "<font color='#CC0000'>Invalid inputs were given to this function.</font>"<font face='Lucida Console'>)</font>;
        Q <font color='#5555FF'>=</font> A<font color='#5555FF'>*</font>matrix_cast<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#BB00BB'>gaussian_randm</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, l<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Q<font face='Lucida Console'>)</font>;

        <font color='#009900'>// Do some extra iterations of the power method to make sure we get Q into the 
</font>        <font color='#009900'>// span of the most important singular vectors of A.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>q <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> itr <font color='#5555FF'>=</font> <font color='#979000'>0</font>; itr <font color='#5555FF'>&lt;</font> q; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>itr<font face='Lucida Console'>)</font>
            <b>{</b>
                Q <font color='#5555FF'>=</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>Q;
                <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Q<font face='Lucida Console'>)</font>;

                Q <font color='#5555FF'>=</font> A<font color='#5555FF'>*</font>Q;
                <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Q<font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> T,
        <font color='#0000FF'><u>long</u></font> Anr, <font color='#0000FF'><u>long</u></font> Anc,
        <font color='#0000FF'><u>long</u></font> Unr, <font color='#0000FF'><u>long</u></font> Unc,
        <font color='#0000FF'><u>long</u></font> Wnr, <font color='#0000FF'><u>long</u></font> Wnc,
        <font color='#0000FF'><u>long</u></font> Vnr, <font color='#0000FF'><u>long</u></font> Vnc,
        <font color='#0000FF'>typename</font> MM,
        <font color='#0000FF'>typename</font> L
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>void</u></font> <b><a name='svd_fast'></a>svd_fast</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font>T,Anr,Anc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A,
        matrix<font color='#5555FF'>&lt;</font>T,Unr,Unc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u,
        matrix<font color='#5555FF'>&lt;</font>T,Wnr,Wnc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> w,
        matrix<font color='#5555FF'>&lt;</font>T,Vnr,Vnc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> l,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> q <font color='#5555FF'>=</font> <font color='#979000'>1</font>
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> k <font color='#5555FF'>=</font> std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font>l, std::min<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>l <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font>, 
            "<font color='#CC0000'>\t void svd_fast()</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t Invalid inputs were given to this function.</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t l: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> l 
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t A.size(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        matrix<font color='#5555FF'>&lt;</font>T,Anr,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font> Q;
        <font color='#BB00BB'>find_matrix_range</font><font face='Lucida Console'>(</font>A, k, Q, q<font face='Lucida Console'>)</font>;

        <font color='#009900'>// Compute trans(B) = trans(Q)*A.   The reason we store B transposed
</font>        <font color='#009900'>// is so that when we take its SVD later using svd3() it doesn't consume
</font>        <font color='#009900'>// a whole lot of RAM.  That is, we make sure the square matrix coming out
</font>        <font color='#009900'>// of svd3() has size lxl rather than the potentially much larger nxn.
</font>        matrix<font color='#5555FF'>&lt;</font>T,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font> B <font color='#5555FF'>=</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>Q;
        <font color='#BB00BB'>svd3</font><font face='Lucida Console'>(</font>B, v,w,u<font face='Lucida Console'>)</font>;
        u <font color='#5555FF'>=</font> Q<font color='#5555FF'>*</font>u;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> sparse_vector_type, 
        <font color='#0000FF'>typename</font> T,
        <font color='#0000FF'>typename</font> MM,
        <font color='#0000FF'>typename</font> L
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>void</u></font> <b><a name='find_matrix_range'></a>find_matrix_range</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>sparse_vector_type<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> l,
        matrix<font color='#5555FF'>&lt;</font>T,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> Q,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> q 
    <font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        requires
            - A.size() &gt;= l
        ensures
            - #Q.nr() == A.size()
            - #Q.nc() == l
            - #Q == an orthonormal matrix whose range approximates the range of the
              matrix A.  In this case, we interpret A as a matrix of A.size() rows,
              where each row is defined by a sparse vector.
            - This function implements the randomized subspace iteration defined 
              in the algorithm 4.4 box of the paper: 
                Finding Structure with Randomness: Probabilistic Algorithms for
                Constructing Approximate Matrix Decompositions by Halko et al.
            - q defines the number of extra subspace iterations this algorithm will
              perform.  Often q == 0 is fine, but performing more iterations can lead to a
              more accurate approximation of the range of A if A has slowly decaying
              singular values.  In these cases, using a q of 1 or 2 is good.
    !*/</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> l, "<font color='#CC0000'>Invalid inputs were given to this function.</font>"<font face='Lucida Console'>)</font>;
        Q.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, l<font face='Lucida Console'>)</font>;

        <font color='#009900'>// Compute Q = A*gaussian_randm()
</font>        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> Q.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>0</font>; c <font color='#5555FF'>&lt;</font> Q.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>Q</font><font face='Lucida Console'>(</font>r,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>dot</font><font face='Lucida Console'>(</font>A[r], <font color='#BB00BB'>gaussian_randm</font><font face='Lucida Console'>(</font>std::numeric_limits<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>max</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, <font color='#979000'>1</font>, c<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>

        <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Q<font face='Lucida Console'>)</font>;

        <font color='#009900'>// Do some extra iterations of the power method to make sure we get Q into the 
</font>        <font color='#009900'>// span of the most important singular vectors of A.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>q <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> n <font color='#5555FF'>=</font> <font color='#BB00BB'>max_index_plus_one</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> itr <font color='#5555FF'>=</font> <font color='#979000'>0</font>; itr <font color='#5555FF'>&lt;</font> q; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>itr<font face='Lucida Console'>)</font>
            <b>{</b>
                matrix<font color='#5555FF'>&lt;</font>T,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>Z</font><font face='Lucida Console'>(</font>n, l<font face='Lucida Console'>)</font>;
                <font color='#009900'>// Compute Z = trans(A)*Q
</font>                Z <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> m <font color='#5555FF'>=</font> <font color='#979000'>0</font>; m <font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>m<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> l; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#0000FF'>typename</font> sparse_vector_type::const_iterator i;
                        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i <font color='#5555FF'>=</font> A[m].<font color='#BB00BB'>begin</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; i <font color='#5555FF'>!</font><font color='#5555FF'>=</font> A[m].<font color='#BB00BB'>end</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                        <b>{</b>
                            <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> i<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>first;
                            <font color='#0000FF'>const</font> T val <font color='#5555FF'>=</font> i<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>second;

                            <font color='#BB00BB'>Z</font><font face='Lucida Console'>(</font>c,r<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#BB00BB'>Q</font><font face='Lucida Console'>(</font>m,r<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>val;
                        <b>}</b>
                    <b>}</b>
                <b>}</b>

                Q.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>; <font color='#009900'>// free RAM
</font>                <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Z<font face='Lucida Console'>)</font>;

                <font color='#009900'>// Compute Q = A*Z
</font>                Q.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, l<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> Q.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>0</font>; c <font color='#5555FF'>&lt;</font> Q.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
                    <b>{</b>
                        <font color='#BB00BB'>Q</font><font face='Lucida Console'>(</font>r,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>dot</font><font face='Lucida Console'>(</font>A[r], <font color='#BB00BB'>colm</font><font face='Lucida Console'>(</font>Z,c<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                    <b>}</b>
                <b>}</b>

                Z.<font color='#BB00BB'>set_size</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>; <font color='#009900'>// free RAM
</font>                <font color='#BB00BB'>orthogonalize</font><font face='Lucida Console'>(</font>Q<font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> sparse_vector_type, 
        <font color='#0000FF'>typename</font> T,
        <font color='#0000FF'><u>long</u></font> Unr, <font color='#0000FF'><u>long</u></font> Unc,
        <font color='#0000FF'><u>long</u></font> Wnr, <font color='#0000FF'><u>long</u></font> Wnc,
        <font color='#0000FF'><u>long</u></font> Vnr, <font color='#0000FF'><u>long</u></font> Vnc,
        <font color='#0000FF'>typename</font> MM,
        <font color='#0000FF'>typename</font> L
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'><u>void</u></font> <b><a name='svd_fast'></a>svd_fast</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> std::vector<font color='#5555FF'>&lt;</font>sparse_vector_type<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A,
        matrix<font color='#5555FF'>&lt;</font>T,Unr,Unc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u,
        matrix<font color='#5555FF'>&lt;</font>T,Wnr,Wnc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> w,
        matrix<font color='#5555FF'>&lt;</font>T,Vnr,Vnc,MM,L<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> l,
        <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> q <font color='#5555FF'>=</font> <font color='#979000'>1</font>
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> n <font color='#5555FF'>=</font> <font color='#BB00BB'>max_index_plus_one</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> k <font color='#5555FF'>=</font> std::<font color='#BB00BB'>min</font><font face='Lucida Console'>(</font>l, std::min<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,n<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>l <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font> <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> n <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font>, 
            "<font color='#CC0000'>\t void svd_fast()</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t Invalid inputs were given to this function.</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t l: </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> l 
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t n (i.e. max_index_plus_one(A)): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> n 
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t A.size(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        matrix<font color='#5555FF'>&lt;</font>T,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font> Q;
        <font color='#BB00BB'>find_matrix_range</font><font face='Lucida Console'>(</font>A, k, Q, q<font face='Lucida Console'>)</font>;

        <font color='#009900'>// Compute trans(B) = trans(Q)*A.   The reason we store B transposed
</font>        <font color='#009900'>// is so that when we take its SVD later using svd3() it doesn't consume
</font>        <font color='#009900'>// a whole lot of RAM.  That is, we make sure the square matrix coming out
</font>        <font color='#009900'>// of svd3() has size lxl rather than the potentially much larger nxn.
</font>        matrix<font color='#5555FF'>&lt;</font>T,<font color='#979000'>0</font>,<font color='#979000'>0</font>,MM,L<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>B</font><font face='Lucida Console'>(</font>n,k<font face='Lucida Console'>)</font>;
        B <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> m <font color='#5555FF'>=</font> <font color='#979000'>0</font>; m <font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>m<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> k; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>typename</font> sparse_vector_type::const_iterator i;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font>i <font color='#5555FF'>=</font> A[m].<font color='#BB00BB'>begin</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; i <font color='#5555FF'>!</font><font color='#5555FF'>=</font> A[m].<font color='#BB00BB'>end</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                <b>{</b>
                    <font color='#0000FF'>const</font> <font color='#0000FF'><u>unsigned</u></font> <font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> i<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>first;
                    <font color='#0000FF'>const</font> T val <font color='#5555FF'>=</font> i<font color='#5555FF'>-</font><font color='#5555FF'>&gt;</font>second;

                    <font color='#BB00BB'>B</font><font face='Lucida Console'>(</font>c,r<font face='Lucida Console'>)</font> <font color='#5555FF'>+</font><font color='#5555FF'>=</font> <font color='#BB00BB'>Q</font><font face='Lucida Console'>(</font>m,r<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>val;
                <b>}</b>
            <b>}</b>
        <b>}</b>

        <font color='#BB00BB'>svd3</font><font face='Lucida Console'>(</font>B, v,w,u<font face='Lucida Console'>)</font>;
        u <font color='#5555FF'>=</font> Q<font color='#5555FF'>*</font>u;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font><font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> N
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='inv_helper'></a>inv_helper</b>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// you can't invert a non-square matrix
</font>            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>|</font><font color='#5555FF'>|</font> 
                                matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                                matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
                "<font color='#CC0000'>\tconst matrix_exp::type inv(const matrix_exp&amp; m)</font>"
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou can only apply inv() to a square matrix</font>"
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
                <font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            lu_decomposition<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>lu</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> lu.<font color='#BB00BB'>solve</font><font face='Lucida Console'>(</font>identity_matrix<font color='#5555FF'>&lt;</font>type<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='inv_helper'></a>inv_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            matrix<font color='#5555FF'>&lt;</font>type, <font color='#979000'>1</font>, <font color='#979000'>1</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> a;
            <font color='#009900'>// if m is invertible
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1</font><font color='#5555FF'>/</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>else</font>
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
            <font color='#0000FF'>return</font> a;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='inv_helper'></a>inv_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            matrix<font color='#5555FF'>&lt;</font>type, <font color='#979000'>2</font>, <font color='#979000'>2</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> a;
            type d <font color='#5555FF'>=</font> <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>d <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                d <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font>type<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#979000'>1.0</font><font color='#5555FF'>/</font>d<font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>d;
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#5555FF'>-</font>d;
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#5555FF'>-</font>d;
                <font color='#BB00BB'>a</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font>d;
            <b>}</b>
            <font color='#0000FF'>else</font>
            <b>{</b>
                <font color='#009900'>// Matrix isn't invertible so just return the identity matrix.
</font>                a <font color='#5555FF'>=</font> identity_matrix<font color='#5555FF'>&lt;</font>type,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <b>}</b>
            <font color='#0000FF'>return</font> a;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='inv_helper'></a>inv_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            matrix<font color='#5555FF'>&lt;</font>type, <font color='#979000'>3</font>, <font color='#979000'>3</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> ret;
            type de <font color='#5555FF'>=</font> <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>de <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                de <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font>type<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#979000'>1.0</font><font color='#5555FF'>/</font>de<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type a <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type b <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type c <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type d <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type e <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type f <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type g <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type h <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'>const</font> type i <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font>;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>e<font color='#5555FF'>*</font>i <font color='#5555FF'>-</font> f<font color='#5555FF'>*</font>h<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>f<font color='#5555FF'>*</font>g <font color='#5555FF'>-</font> d<font color='#5555FF'>*</font>i<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>d<font color='#5555FF'>*</font>h <font color='#5555FF'>-</font> e<font color='#5555FF'>*</font>g<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>c<font color='#5555FF'>*</font>h <font color='#5555FF'>-</font> b<font color='#5555FF'>*</font>i<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>a<font color='#5555FF'>*</font>i <font color='#5555FF'>-</font> c<font color='#5555FF'>*</font>g<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>b<font color='#5555FF'>*</font>g <font color='#5555FF'>-</font> a<font color='#5555FF'>*</font>h<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>b<font color='#5555FF'>*</font>f <font color='#5555FF'>-</font> c<font color='#5555FF'>*</font>e<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>c<font color='#5555FF'>*</font>d <font color='#5555FF'>-</font> a<font color='#5555FF'>*</font>f<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>a<font color='#5555FF'>*</font>e <font color='#5555FF'>-</font> b<font color='#5555FF'>*</font>d<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
            <b>}</b>
            <font color='#0000FF'>else</font>
            <b>{</b>
                ret <font color='#5555FF'>=</font> identity_matrix<font color='#5555FF'>&lt;</font>type,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <b>}</b>

            <font color='#0000FF'>return</font> ret;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='inv_helper'></a>inv_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>4</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            matrix<font color='#5555FF'>&lt;</font>type, <font color='#979000'>4</font>, <font color='#979000'>4</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> ret;
            type de <font color='#5555FF'>=</font> <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>de <font color='#5555FF'>!</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <b>{</b>
                de <font color='#5555FF'>=</font> <font color='#0000FF'>static_cast</font><font color='#5555FF'>&lt;</font>type<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#979000'>1.0</font><font color='#5555FF'>/</font>de<font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>3</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>3</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>1</font>,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>3</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>2</font>,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>3</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>3</font>,<font color='#979000'>0</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>3</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>3</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>3</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>3</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#BB00BB'>ret</font><font face='Lucida Console'>(</font><font color='#979000'>3</font>,<font color='#979000'>3</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font>  <font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>3</font>,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

                <font color='#0000FF'>return</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>ret<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>de;
            <b>}</b>
            <font color='#0000FF'>else</font>
            <b>{</b>
                <font color='#0000FF'>return</font> identity_matrix<font color='#5555FF'>&lt;</font>type,<font color='#979000'>4</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>inline</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font> <b>{</b> <font color='#0000FF'>return</font> inv_helper<font color='#5555FF'>&lt;</font>EXP,matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>inv</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>; <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> M<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='op_diag_inv'></a>op_diag_inv</b>
    <b>{</b>
        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP<font color='#5555FF'>&gt;</font>
        <b><a name='op_diag_inv'></a>op_diag_inv</b><font face='Lucida Console'>(</font> <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m_<font face='Lucida Console'>)</font> : m<font face='Lucida Console'>(</font>m_<font face='Lucida Console'>)</font><b>{</b><b>}</b>


        <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>long</u></font> cost <font color='#5555FF'>=</font> <font color='#979000'>1</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>long</u></font> NR <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>M::NC<font color='#5555FF'>!</font><font color='#5555FF'>=</font><font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font><font face='Lucida Console'>(</font>M::NR<font color='#5555FF'>!</font><font color='#5555FF'>=</font><font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>? <font face='Lucida Console'>(</font>tmax<font color='#5555FF'>&lt;</font>M::NR,M::NC<font color='#5555FF'>&gt;</font>::value<font face='Lucida Console'>)</font> : <font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'>static</font> <font color='#0000FF'><u>long</u></font> NC <font color='#5555FF'>=</font> NR;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> M::type type;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>const</font> type const_ret_type;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> M::mem_manager_type mem_manager_type;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> M::layout_type layout_type;


        <font color='#009900'>// hold the matrix by value
</font>        <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font>type,NR,<font color='#979000'>1</font>,mem_manager_type,layout_type<font color='#5555FF'>&gt;</font> m;

        const_ret_type apply <font face='Lucida Console'>(</font> <font color='#0000FF'><u>long</u></font> r, <font color='#0000FF'><u>long</u></font> c<font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> 
        <b>{</b> 
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>r<font color='#5555FF'>=</font><font color='#5555FF'>=</font>c<font face='Lucida Console'>)</font>
                <font color='#0000FF'>return</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>r<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> <font color='#979000'>0</font>;
        <b>}</b>

        <font color='#0000FF'><u>long</u></font> <b><a name='nr'></a>nr</b> <font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> m.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <b>}</b>
        <font color='#0000FF'><u>long</u></font> <b><a name='nc'></a>nc</b> <font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> m.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <b>}</b>

        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> U<font color='#5555FF'>&gt;</font> <font color='#0000FF'><u>bool</u></font> <b><a name='aliases'></a>aliases</b>               <font face='Lucida Console'>(</font> <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>U<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> item<font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> m.<font color='#BB00BB'>aliases</font><font face='Lucida Console'>(</font>item<font face='Lucida Console'>)</font>; <b>}</b>
        <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> U<font color='#5555FF'>&gt;</font> <font color='#0000FF'><u>bool</u></font> <b><a name='destructively_aliases'></a>destructively_aliases</b> <font face='Lucida Console'>(</font> <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>U<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> item<font face='Lucida Console'>)</font> <font color='#0000FF'>const</font> <b>{</b> <font color='#0000FF'>return</font> m.<font color='#BB00BB'>aliases</font><font face='Lucida Console'>(</font>item<font face='Lucida Console'>)</font>; <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> <font color='#5555FF'>&gt;</font> <b><a name='inv'></a>inv</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_diag_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font> 
    <b>{</b> 
        <font color='#0000FF'>typedef</font> op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> op;
        <font color='#0000FF'>return</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#BB00BB'>op</font><font face='Lucida Console'>(</font><font color='#BB00BB'>reciprocal</font><font face='Lucida Console'>(</font><font color='#BB00BB'>diag</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
    <b>}</b>

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> <font color='#5555FF'>&gt;</font> <b><a name='pinv'></a>pinv</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_diag_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font> 
    <b>{</b> 
        <font color='#0000FF'>typedef</font> op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> op;
        <font color='#0000FF'>return</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#BB00BB'>op</font><font face='Lucida Console'>(</font><font color='#BB00BB'>reciprocal</font><font face='Lucida Console'>(</font><font color='#BB00BB'>diag</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> <font color='#5555FF'>&gt;</font> <b><a name='pinv'></a>pinv</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_diag_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m,
        <font color='#0000FF'><u>double</u></font> tol
    <font face='Lucida Console'>)</font> 
    <b>{</b> 
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>tol <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> <font color='#979000'>0</font>, 
            "<font color='#CC0000'>\tconst matrix_exp::type pinv(const matrix_exp&amp; m)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t tol can't be negative</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t tol: </font>"<font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font>tol 
            <font face='Lucida Console'>)</font>;
        <font color='#0000FF'>typedef</font> op_diag_inv<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font> op;
        <font color='#0000FF'>return</font> matrix_diag_op<font color='#5555FF'>&lt;</font>op<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#BB00BB'>op</font><font face='Lucida Console'>(</font><font color='#BB00BB'>reciprocal</font><font face='Lucida Console'>(</font><font color='#BB00BB'>round_zeros</font><font face='Lucida Console'>(</font><font color='#BB00BB'>diag</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>,tol<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type  <b><a name='inv_lower_triangular'></a>inv_lower_triangular</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A 
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix inv_lower_triangular(const matrix_exp&amp; A)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA must be a square matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type matrix_type;

        matrix_type <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>for</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>0</font>; c <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>if</font><font face='Lucida Console'>(</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// there isn't an inverse so just give up
</font>                <font color='#0000FF'>return</font> m;
            <b>}</b>

            <font color='#009900'>// compute m(c,c)
</font>            <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1</font><font color='#5555FF'>/</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font>;

            <font color='#009900'>// compute the values in column c that are below m(c,c).
</font>            <font color='#009900'>// We do this by just doing the same thing we do for upper triangular
</font>            <font color='#009900'>// matrices because we take the transpose of m which turns m into an
</font>            <font color='#009900'>// upper triangular matrix.
</font>            <font color='#0000FF'>for</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> c; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> n <font color='#5555FF'>=</font> c<font color='#5555FF'>-</font>r;
                <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,r<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>subm</font><font face='Lucida Console'>(</font><font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>,r,r,<font color='#979000'>1</font>,n<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>subm</font><font face='Lucida Console'>(</font><font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>,r,c,n,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>return</font> m;

    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type  <b><a name='inv_upper_triangular'></a>inv_upper_triangular</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A 
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix inv_upper_triangular(const matrix_exp&amp; A)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA must be a square matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type matrix_type;

        matrix_type <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>A<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>for</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>0</font>; c <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>if</font><font face='Lucida Console'>(</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#009900'>// there isn't an inverse so just give up
</font>                <font color='#0000FF'>return</font> m;
            <b>}</b>

            <font color='#009900'>// compute m(c,c)
</font>            <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#979000'>1</font><font color='#5555FF'>/</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font>;

            <font color='#009900'>// compute the values in column c that are above m(c,c)
</font>            <font color='#0000FF'>for</font><font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>0</font>; r <font color='#5555FF'>&lt;</font> c; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> n <font color='#5555FF'>=</font> c<font color='#5555FF'>-</font>r;
                <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>r,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>subm</font><font face='Lucida Console'>(</font>m,r,r,<font color='#979000'>1</font>,n<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>subm</font><font face='Lucida Console'>(</font>m,r,c,n,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>return</font> m;

    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>inline</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <b><a name='chol'></a>chol</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> A
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix chol(const matrix_exp&amp; A)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou can only apply the chol to a square matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tA.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;
        <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

<font color='#0000FF'>#ifdef</font> DLIB_USE_LAPACK
        <font color='#009900'>// Only call LAPACK if the matrix is big enough.  Otherwise,
</font>        <font color='#009900'>// our own code is faster, especially for statically dimensioned 
</font>        <font color='#009900'>// matrices.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> <font color='#979000'>4</font><font face='Lucida Console'>)</font>
        <b>{</b>
            L <font color='#5555FF'>=</font> A;
            lapack::<font color='#BB00BB'>potrf</font><font face='Lucida Console'>(</font>'<font color='#FF0000'>L</font>', L<font face='Lucida Console'>)</font>;
            <font color='#009900'>// mask out upper triangular area
</font>            <font color='#0000FF'>return</font> <font color='#BB00BB'>lowerm</font><font face='Lucida Console'>(</font>L<font face='Lucida Console'>)</font>;
        <b>}</b>
<font color='#0000FF'>#endif</font>
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> EXP::type T;
        <font color='#BB00BB'>set_all_elements</font><font face='Lucida Console'>(</font>L,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;

        <font color='#009900'>// do nothing if the matrix is empty
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>A.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> L;

        <font color='#0000FF'>const</font> T eps <font color='#5555FF'>=</font> std::numeric_limits<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>epsilon</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;

        <font color='#009900'>// compute the upper left corner
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>A</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> std::<font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font><font color='#BB00BB'>A</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#009900'>// compute the first column
</font>        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#979000'>1</font>; r <font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// if (L(0,0) &gt; 0)
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> eps<font color='#5555FF'>*</font>std::<font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font><font color='#BB00BB'>A</font><font face='Lucida Console'>(</font>r,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>r,<font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font color='#BB00BB'>A</font><font face='Lucida Console'>(</font>r,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>/</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>else</font>
                <font color='#0000FF'>return</font> L;
        <b>}</b>

        <font color='#009900'>// now compute all the other columns
</font>        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#979000'>1</font>; c <font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#009900'>// compute the diagonal element
</font>            T temp <font color='#5555FF'>=</font> <font color='#BB00BB'>A</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> c; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
            <b>{</b>
                temp <font color='#5555FF'>-</font><font color='#5555FF'>=</font> <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,i<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,i<font face='Lucida Console'>)</font>;
            <b>}</b>
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>temp <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> std::<font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font>;

            <font color='#009900'>// compute the non diagonal elements
</font>            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> c<font color='#5555FF'>+</font><font color='#979000'>1</font>; r <font color='#5555FF'>&lt;</font> A.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
            <b>{</b>
                temp <font color='#5555FF'>=</font> <font color='#BB00BB'>A</font><font face='Lucida Console'>(</font>r,c<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>; i <font color='#5555FF'>&lt;</font> c; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i<font face='Lucida Console'>)</font>
                <b>{</b>
                    temp <font color='#5555FF'>-</font><font color='#5555FF'>=</font> <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>r,i<font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,i<font face='Lucida Console'>)</font>;
                <b>}</b>

                <font color='#009900'>// if (L(c,c) &gt; 0)
</font>                <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> eps<font color='#5555FF'>*</font>std::<font color='#BB00BB'>abs</font><font face='Lucida Console'>(</font>temp<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
                    <font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>r,c<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> temp<font color='#5555FF'>/</font><font color='#BB00BB'>L</font><font face='Lucida Console'>(</font>c,c<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>else</font>
                    <font color='#0000FF'>return</font> L;
            <b>}</b>
        <b>}</b>

        <font color='#0000FF'>return</font> L;

    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> uNR, 
        <font color='#0000FF'><u>long</u></font> uNC,
        <font color='#0000FF'><u>long</u></font> wN, 
        <font color='#0000FF'><u>long</u></font> vN,
        <font color='#0000FF'><u>long</u></font> wX,
        <font color='#0000FF'>typename</font> MM1,
        <font color='#0000FF'>typename</font> MM2,
        <font color='#0000FF'>typename</font> MM3,
        <font color='#0000FF'>typename</font> L1
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>inline</font> <font color='#0000FF'><u>void</u></font> <b><a name='svd3'></a>svd3</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, uNR, uNC,MM1,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, wN, wX,MM2,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> w,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, vN, vN,MM3,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type T;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NR <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NC <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC;

        <font color='#009900'>// make sure the output matrices have valid dimensions if they are statically dimensioned
</font>        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> uNR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> uNR<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> uNC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> uNC<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> wN <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> wN<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> vN <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> vN<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>wX <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> wX <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>1</font><font face='Lucida Console'>)</font>;

<font color='#0000FF'>#ifdef</font> DLIB_USE_LAPACK
        <font color='#009900'>// use LAPACK but only if it isn't a really small matrix we are taking the SVD of.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>NR<font color='#5555FF'>*</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NR<font color='#5555FF'>*</font>NC <font color='#5555FF'>&gt;</font> <font color='#979000'>3</font><font color='#5555FF'>*</font><font color='#979000'>3</font><font face='Lucida Console'>)</font>
        <b>{</b>
            matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, uNR, uNC,MM1,L1<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>temp</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;
            lapack::<font color='#BB00BB'>gesvd</font><font face='Lucida Console'>(</font>'<font color='#FF0000'>S</font>','<font color='#FF0000'>A</font>', temp, w, u, v<font face='Lucida Console'>)</font>;
            v <font color='#5555FF'>=</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>v<font face='Lucida Console'>)</font>;
            <font color='#009900'>// if u isn't the size we want then pad it (and v) with zeros
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                w <font color='#5555FF'>=</font> <font color='#BB00BB'>join_cols</font><font face='Lucida Console'>(</font>w, zeros_matrix<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                u <font color='#5555FF'>=</font> <font color='#BB00BB'>join_rows</font><font face='Lucida Console'>(</font>u, zeros_matrix<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>u.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>
            <font color='#0000FF'>return</font>;
        <b>}</b>
<font color='#0000FF'>#endif</font>
        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>svd4</font><font face='Lucida Console'>(</font>SVD_SKINNY_U,<font color='#979000'>true</font>, m, u,w,v<font face='Lucida Console'>)</font>;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            <font color='#BB00BB'>svd4</font><font face='Lucida Console'>(</font>SVD_FULL_U,<font color='#979000'>true</font>, <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>, v,w,u<font face='Lucida Console'>)</font>;

            <font color='#009900'>// if u isn't the size we want then pad it (and v) with zeros
</font>            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                w <font color='#5555FF'>=</font> <font color='#BB00BB'>join_cols</font><font face='Lucida Console'>(</font>w, zeros_matrix<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                u <font color='#5555FF'>=</font> <font color='#BB00BB'>join_rows</font><font face='Lucida Console'>(</font>u, zeros_matrix<font color='#5555FF'>&lt;</font>T<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>u.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>-</font>u.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,EXP::NC,EXP::NR,<font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> <b><a name='pinv_helper'></a>pinv_helper</b> <font face='Lucida Console'>(</font> 
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m,
        <font color='#0000FF'><u>double</u></font> tol
    <font face='Lucida Console'>)</font>
    <font color='#009900'>/*!
        ensures
            - computes the results of pinv(m) but does so using a method that is fastest
              when m.nc() &lt;= m.nr().  So if m.nc() &gt; m.nr() then it is best to use
              trans(pinv_helper(trans(m))) to compute pinv(m).
    !*/</font>
    <b>{</b> 
        <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::matrix_type u;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> EXP::mem_manager_type MM1;
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> EXP::layout_type layout_type;
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type, EXP::NC, EXP::NC,MM1, layout_type <font color='#5555FF'>&gt;</font> v;

        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type T;

        matrix<font color='#5555FF'>&lt;</font>T,matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC,<font color='#979000'>1</font>,MM1, layout_type<font color='#5555FF'>&gt;</font> w;

        <font color='#BB00BB'>svd3</font><font face='Lucida Console'>(</font>m, u,w,v<font face='Lucida Console'>)</font>;

        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> machine_eps <font color='#5555FF'>=</font> std::numeric_limits<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>epsilon</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <font color='#009900'>// compute a reasonable epsilon below which we round to zero before doing the
</font>        <font color='#009900'>// reciprocal.  Unless a non-zero tol is given then we just use tol*max(w).
</font>        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> eps <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font>tol<font color='#5555FF'>!</font><font color='#5555FF'>=</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> ? tol<font color='#5555FF'>*</font><font color='#BB00BB'>max</font><font face='Lucida Console'>(</font>w<font face='Lucida Console'>)</font> :  machine_eps<font color='#5555FF'>*</font>std::<font color='#BB00BB'>max</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>,m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>max</font><font face='Lucida Console'>(</font>w<font face='Lucida Console'>)</font>;

        <font color='#009900'>// now compute the pseudoinverse
</font>        <font color='#0000FF'>return</font> <font color='#BB00BB'>tmp</font><font face='Lucida Console'>(</font><font color='#BB00BB'>scale_columns</font><font face='Lucida Console'>(</font>v,<font color='#BB00BB'>reciprocal</font><font face='Lucida Console'>(</font><font color='#BB00BB'>round_zeros</font><font face='Lucida Console'>(</font>w,eps<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>u<font face='Lucida Console'>)</font>;
    <b>}</b>

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type,EXP::NC,EXP::NR,<font color='#0000FF'>typename</font> EXP::mem_manager_type<font color='#5555FF'>&gt;</font> <b><a name='pinv'></a>pinv</b> <font face='Lucida Console'>(</font> 
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m,
        <font color='#0000FF'><u>double</u></font> tol <font color='#5555FF'>=</font> <font color='#979000'>0</font>
    <font face='Lucida Console'>)</font>
    <b>{</b> 
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>tol <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> <font color='#979000'>0</font>, 
            "<font color='#CC0000'>\tconst matrix_exp::type pinv(const matrix_exp&amp; m)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t tol can't be negative</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\t tol: </font>"<font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font>tol 
            <font face='Lucida Console'>)</font>;
        <font color='#009900'>// if m has more columns then rows then it is more efficient to
</font>        <font color='#009900'>// compute the pseudo-inverse of its transpose (given the way I'm doing it below).
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> <font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font><font color='#BB00BB'>pinv_helper</font><font face='Lucida Console'>(</font><font color='#BB00BB'>trans</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>,tol<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>else</font>
            <font color='#0000FF'>return</font> <font color='#BB00BB'>pinv_helper</font><font face='Lucida Console'>(</font>m,tol<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> uNR, 
        <font color='#0000FF'><u>long</u></font> uNC,
        <font color='#0000FF'><u>long</u></font> wN, 
        <font color='#0000FF'><u>long</u></font> vN,
        <font color='#0000FF'>typename</font> MM1,
        <font color='#0000FF'>typename</font> MM2,
        <font color='#0000FF'>typename</font> MM3,
        <font color='#0000FF'>typename</font> L1
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>inline</font> <font color='#0000FF'><u>void</u></font> <b><a name='svd'></a>svd</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, uNR, uNC,MM1,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> u,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, wN, wN,MM2,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> w,
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type, vN, vN,MM3,L1<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> v
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type T;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NR <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> NC <font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC;

        <font color='#009900'>// make sure the output matrices have valid dimensions if they are statically dimensioned
</font>        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> uNR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> uNR<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> uNC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> uNC<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> wN <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> wN<font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> vN <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font> NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> vN<font face='Lucida Console'>)</font>;

        matrix<font color='#5555FF'>&lt;</font>T,matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC,<font color='#979000'>1</font>,MM1, L1<font color='#5555FF'>&gt;</font> W;
        <font color='#BB00BB'>svd3</font><font face='Lucida Console'>(</font>m,u,W,v<font face='Lucida Console'>)</font>;
        w <font color='#5555FF'>=</font> <font color='#BB00BB'>diagm</font><font face='Lucida Console'>(</font>W<font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='trace'></a>trace</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font> 
    <b>{</b> 
        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                            matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                            matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> 
                            <font face='Lucida Console'>)</font>;
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix_exp::type trace(const matrix_exp&amp; m)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou can only apply trace() to a square matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;
        <font color='#0000FF'>return</font> <font color='#BB00BB'>sum</font><font face='Lucida Console'>(</font><font color='#BB00BB'>diag</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP,
        <font color='#0000FF'><u>long</u></font> N <font color='#5555FF'>=</font> EXP::NR
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='det_helper'></a>det_helper</b>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                                matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                                matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>0</font> 
                                <font face='Lucida Console'>)</font>;
            <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
                "<font color='#CC0000'>\tconst matrix_exp::type det(const matrix_exp&amp; m)</font>"
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou can only apply det() to a square matrix</font>"
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
                <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
                <font face='Lucida Console'>)</font>;

            <font color='#0000FF'>return</font> lu_decomposition<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>.<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='det_helper'></a>det_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;

            <font color='#0000FF'>return</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='det_helper'></a>det_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;

            <font color='#0000FF'>return</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>;

    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='det_helper'></a>det_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            type temp <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font>
                        <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font>
                        <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>2</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> temp;
        <b>}</b>
    <b>}</b>;


    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>inline</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font> <b>{</b> <font color='#0000FF'>return</font> det_helper<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>; <b>}</b>


    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP
        <font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>struct</font> <b><a name='det_helper'></a>det_helper</b><font color='#5555FF'>&lt;</font>EXP,<font color='#979000'>4</font><font color='#5555FF'>&gt;</font>
    <b>{</b>
        <font color='#0000FF'>static</font> <font color='#0000FF'>const</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type <b><a name='det'></a>det</b> <font face='Lucida Console'>(</font>
            <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
        <font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font>matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NR <font color='#5555FF'>=</font><font color='#5555FF'>=</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::NC<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font>::type type;

            type temp <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font>
                        <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>+</font>
                        <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font> <font color='#5555FF'>-</font>
                        <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>3</font><font face='Lucida Console'>)</font><font color='#5555FF'>*</font><font face='Lucida Console'>(</font>dlib::<font color='#BB00BB'>det</font><font face='Lucida Console'>(</font>removerc<font color='#5555FF'>&lt;</font><font color='#979000'>0</font>,<font color='#979000'>3</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>return</font> temp;
        <b>}</b>
    <b>}</b>;

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP<font color='#5555FF'>&gt;</font>
    <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type, EXP::NR, <font color='#979000'>1</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type, <font color='#0000FF'>typename</font> EXP::layout_type<font color='#5555FF'>&gt;</font> <b><a name='real_eigenvalues'></a>real_eigenvalues</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#009900'>// You can only use this function with matrices that contain float or double values
</font>        <font color='#BB00BB'>COMPILE_TIME_ASSERT</font><font face='Lucida Console'>(</font><font face='Lucida Console'>(</font>is_same_type<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type, <font color='#0000FF'><u>float</u></font><font color='#5555FF'>&gt;</font>::value <font color='#5555FF'>|</font><font color='#5555FF'>|</font>
                             is_same_type<font color='#5555FF'>&lt;</font><font color='#0000FF'>typename</font> EXP::type, <font color='#0000FF'><u>double</u></font><font color='#5555FF'>&gt;</font>::value<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;

        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>, 
            "<font color='#CC0000'>\tconst matrix real_eigenvalues()</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tYou have given an invalidly sized matrix</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nr(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nc(): </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;

        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>2</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>typedef</font> <font color='#0000FF'>typename</font> EXP::type T;
            <font color='#0000FF'>const</font> T m00 <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> T m01 <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> T m10 <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> T m11 <font color='#5555FF'>=</font> <font color='#BB00BB'>m</font><font face='Lucida Console'>(</font><font color='#979000'>1</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>;

            <font color='#0000FF'>const</font> T b <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font face='Lucida Console'>(</font>m00 <font color='#5555FF'>+</font> m11<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>const</font> T c <font color='#5555FF'>=</font> m00<font color='#5555FF'>*</font>m11 <font color='#5555FF'>-</font> m01<font color='#5555FF'>*</font>m10;
            matrix<font color='#5555FF'>&lt;</font>T,EXP::NR,<font color='#979000'>1</font>, <font color='#0000FF'>typename</font> EXP::mem_manager_type, <font color='#0000FF'>typename</font> EXP::layout_type<font color='#5555FF'>&gt;</font> <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font><font color='#979000'>2</font><font face='Lucida Console'>)</font>;


            T disc <font color='#5555FF'>=</font> b<font color='#5555FF'>*</font>b <font color='#5555FF'>-</font> <font color='#979000'>4</font><font color='#5555FF'>*</font>c;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>disc <font color='#5555FF'>&gt;</font><font color='#5555FF'>=</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
                disc <font color='#5555FF'>=</font> std::<font color='#BB00BB'>sqrt</font><font face='Lucida Console'>(</font>disc<font face='Lucida Console'>)</font>;
            <font color='#0000FF'>else</font>
                disc <font color='#5555FF'>=</font> <font color='#979000'>0</font>;

            <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#5555FF'>-</font>b <font color='#5555FF'>+</font> disc<font face='Lucida Console'>)</font><font color='#5555FF'>/</font><font color='#979000'>2</font>;
            <font color='#BB00BB'>v</font><font face='Lucida Console'>(</font><font color='#979000'>1</font><font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> <font face='Lucida Console'>(</font><font color='#5555FF'>-</font>b <font color='#5555FF'>-</font> disc<font face='Lucida Console'>)</font><font color='#5555FF'>/</font><font color='#979000'>2</font>;
            <font color='#0000FF'>return</font> v;
        <b>}</b>
        <font color='#0000FF'>else</font>
        <b>{</b>
            <font color='#009900'>// Call .ref() so that the symmetric matrix overload can take effect if m 
</font>            <font color='#009900'>// has the appropriate type.
</font>            <font color='#0000FF'>return</font> eigenvalue_decomposition<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>ref</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>get_real_eigenvalues</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
        <b>}</b>
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
    <font color='#0000FF'>template</font> <font color='#5555FF'>&lt;</font>
        <font color='#0000FF'>typename</font> EXP 
        <font color='#5555FF'>&gt;</font>
    dlib::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font> <b><a name='max_point_interpolated'></a>max_point_interpolated</b> <font face='Lucida Console'>(</font>
        <font color='#0000FF'>const</font> matrix_exp<font color='#5555FF'>&lt;</font>EXP<font color='#5555FF'>&gt;</font><font color='#5555FF'>&amp;</font> m
    <font face='Lucida Console'>)</font>
    <b>{</b>
        <font color='#BB00BB'>DLIB_ASSERT</font><font face='Lucida Console'>(</font>m.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> <font color='#5555FF'>&gt;</font> <font color='#979000'>0</font>, 
            "<font color='#CC0000'>\tdlib::vector&lt;double,2&gt; point max_point_interpolated(const matrix_exp&amp; m)</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm can't be empty</font>"
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.size():   </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>size</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nr():     </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> "<font color='#CC0000'>\n\tm.nc():     </font>" <font color='#5555FF'>&lt;</font><font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font> 
            <font face='Lucida Console'>)</font>;
        <font color='#0000FF'>const</font> point p <font color='#5555FF'>=</font> <font color='#BB00BB'>max_point</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>;

        <font color='#009900'>// If this is a column vector then just do interpolation along a line.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>=</font><font color='#5555FF'>=</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> pos <font color='#5555FF'>=</font> p.<font color='#BB00BB'>y</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font> <font color='#5555FF'>&lt;</font> pos <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> pos<font color='#5555FF'>+</font><font color='#979000'>1</font> <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'><u>double</u></font> v1 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> v2 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> v3 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> y <font color='#5555FF'>=</font> <font color='#BB00BB'>lagrange_poly_min_extrap</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>-</font><font color='#979000'>1</font>,pos,pos<font color='#5555FF'>+</font><font color='#979000'>1</font>, <font color='#5555FF'>-</font>v1, <font color='#5555FF'>-</font>v2, <font color='#5555FF'>-</font>v3<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font><font color='#979000'>0</font>,y<font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>
        <font color='#009900'>// If this is a row vector then just do interpolation along a line.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font>m.<font color='#BB00BB'>nr</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>=</font><font color='#5555FF'>=</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>const</font> <font color='#0000FF'><u>long</u></font> pos <font color='#5555FF'>=</font> p.<font color='#BB00BB'>x</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font>;
            <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#979000'>0</font> <font color='#5555FF'>&lt;</font> pos <font color='#5555FF'>&amp;</font><font color='#5555FF'>&amp;</font> pos<font color='#5555FF'>+</font><font color='#979000'>1</font> <font color='#5555FF'>&lt;</font> m.<font color='#BB00BB'>nc</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#0000FF'><u>double</u></font> v1 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>-</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> v2 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> v3 <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>+</font><font color='#979000'>1</font><font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#0000FF'><u>double</u></font> x <font color='#5555FF'>=</font> <font color='#BB00BB'>lagrange_poly_min_extrap</font><font face='Lucida Console'>(</font>pos<font color='#5555FF'>-</font><font color='#979000'>1</font>,pos,pos<font color='#5555FF'>+</font><font color='#979000'>1</font>, <font color='#5555FF'>-</font>v1, <font color='#5555FF'>-</font>v2, <font color='#5555FF'>-</font>v3<font face='Lucida Console'>)</font>;
                <font color='#0000FF'>return</font> vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>x,<font color='#979000'>0</font><font face='Lucida Console'>)</font>;
            <b>}</b>
        <b>}</b>


        <font color='#009900'>// If it's on the border then just return the regular max point.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>shrink_rect</font><font face='Lucida Console'>(</font><font color='#BB00BB'>get_rect</font><font face='Lucida Console'>(</font>m<font face='Lucida Console'>)</font>,<font color='#979000'>1</font><font face='Lucida Console'>)</font>.<font color='#BB00BB'>contains</font><font face='Lucida Console'>(</font>p<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font><font color='#5555FF'>=</font> <font color='#979000'>false</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> p;

        <font color='#009900'>//matrix&lt;double&gt; A(9,6);
</font>        <font color='#009900'>//matrix&lt;double,0,1&gt; G(9);
</font>
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>9</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font> pix;
        <font color='#0000FF'><u>long</u></font> i <font color='#5555FF'>=</font> <font color='#979000'>0</font>;
        <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> r <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>; r <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> <font color='#5555FF'>+</font><font color='#979000'>1</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>r<font face='Lucida Console'>)</font>
        <b>{</b>
            <font color='#0000FF'>for</font> <font face='Lucida Console'>(</font><font color='#0000FF'><u>long</u></font> c <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#979000'>1</font>; c <font color='#5555FF'>&lt;</font><font color='#5555FF'>=</font> <font color='#5555FF'>+</font><font color='#979000'>1</font>; <font color='#5555FF'>+</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font>
            <b>{</b>
                <font color='#BB00BB'>pix</font><font face='Lucida Console'>(</font>i<font face='Lucida Console'>)</font> <font color='#5555FF'>=</font> dlib::impl::<font color='#BB00BB'>magnitude</font><font face='Lucida Console'>(</font><font color='#BB00BB'>m</font><font face='Lucida Console'>(</font>p.<font color='#BB00BB'>y</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>+</font>r,p.<font color='#BB00BB'>y</font><font face='Lucida Console'>(</font><font face='Lucida Console'>)</font><font color='#5555FF'>+</font>c<font face='Lucida Console'>)</font><font face='Lucida Console'>)</font>;
                <font color='#009900'>/*
                A(i,0) = c*c;
                A(i,1) = c*r;
                A(i,2) = r*r;
                A(i,3) = c;
                A(i,4) = r;
                A(i,5) = 1;
                G(i) = std::exp(-1*(r*r+c*c)/2.0); // Use a gaussian windowing function around p.
                */</font>
                <font color='#5555FF'>+</font><font color='#5555FF'>+</font>i;
            <b>}</b>
        <b>}</b>

        <font color='#009900'>// This bit of code is how we generated the derivative_filters matrix below.  
</font>        <font color='#009900'>//A = diagm(G)*A; 
</font>        <font color='#009900'>//std::cout &lt;&lt; std::setprecision(20) &lt;&lt; inv(trans(A)*A)*trans(A)*diagm(G) &lt;&lt; std::endl; exit(1);
</font>
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> m10 <font color='#5555FF'>=</font> <font color='#979000'>0.10597077880854270659</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> m21 <font color='#5555FF'>=</font> <font color='#979000'>0.21194155761708535768</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> m28 <font color='#5555FF'>=</font> <font color='#979000'>0.28805844238291455905</font>;
        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> m57 <font color='#5555FF'>=</font> <font color='#979000'>0.57611688476582878504</font>;
        <font color='#009900'>// So this derivative_filters finds the parameters of the quadratic surface that best fits
</font>        <font color='#009900'>// the 3x3 region around p.  Then we find the maximizer of that surface within that
</font>        <font color='#009900'>// small region and return that as the maximum location.
</font>        <font color='#0000FF'>const</font> <font color='#0000FF'><u>double</u></font> derivative_filters[] <font color='#5555FF'>=</font> <b>{</b>
                <font color='#009900'>// xx
</font>                m10,<font color='#5555FF'>-</font>m21,m10,
                m28,<font color='#5555FF'>-</font>m57,m28,
                m10,<font color='#5555FF'>-</font>m21,m10,

                <font color='#009900'>// xy
</font>                <font color='#979000'>0.25</font> ,<font color='#979000'>0</font>,<font color='#5555FF'>-</font><font color='#979000'>0.25</font>,
                <font color='#979000'>0</font>    ,<font color='#979000'>0</font>, <font color='#979000'>0</font>,
                <font color='#5555FF'>-</font><font color='#979000'>0.25</font>,<font color='#979000'>0</font>,<font color='#979000'>0.25</font>,

                <font color='#009900'>// yy
</font>                m10,  m28, m10,
                <font color='#5555FF'>-</font>m21,<font color='#5555FF'>-</font>m57,<font color='#5555FF'>-</font>m21,
                m10,  m28, m10,

                <font color='#009900'>// x
</font>                <font color='#5555FF'>-</font>m10,<font color='#979000'>0</font>,m10,
                <font color='#5555FF'>-</font>m28,<font color='#979000'>0</font>,m28,
                <font color='#5555FF'>-</font>m10,<font color='#979000'>0</font>,m10,

                <font color='#009900'>// y
</font>                <font color='#5555FF'>-</font>m10,<font color='#5555FF'>-</font>m28,<font color='#5555FF'>-</font>m10,
                <font color='#979000'>0</font>,   <font color='#979000'>0</font>,   <font color='#979000'>0</font>,
                m10, m28, m10
            <b>}</b>;
        <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>5</font>,<font color='#979000'>9</font><font color='#5555FF'>&gt;</font> <font color='#BB00BB'>filt</font><font face='Lucida Console'>(</font>derivative_filters<font face='Lucida Console'>)</font>;
        <font color='#009900'>// Now w contains the parameters of the quadratic surface
</font>        <font color='#0000FF'>const</font> matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>5</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font> w <font color='#5555FF'>=</font> filt<font color='#5555FF'>*</font>pix;


        <font color='#009900'>// Now newton step to the max point on the surface
</font>        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font> H;
        matrix<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font>,<font color='#979000'>1</font><font color='#5555FF'>&gt;</font> g;
        H <font color='#5555FF'>=</font> <font color='#979000'>2</font><font color='#5555FF'>*</font><font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>0</font><font face='Lucida Console'>)</font>, <font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>,
              <font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>1</font><font face='Lucida Console'>)</font>, <font color='#979000'>2</font><font color='#5555FF'>*</font><font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>2</font><font face='Lucida Console'>)</font>;
        g <font color='#5555FF'>=</font> <font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>3</font><font face='Lucida Console'>)</font>, 
            <font color='#BB00BB'>w</font><font face='Lucida Console'>(</font><font color='#979000'>4</font><font face='Lucida Console'>)</font>;
        <font color='#0000FF'>const</font> dlib::vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font> delta <font color='#5555FF'>=</font> <font color='#5555FF'>-</font><font color='#BB00BB'>inv</font><font face='Lucida Console'>(</font>H<font face='Lucida Console'>)</font><font color='#5555FF'>*</font>g;

        <font color='#009900'>// if delta isn't in an ascent direction then just use the normal max point.
</font>        <font color='#0000FF'>if</font> <font face='Lucida Console'>(</font><font color='#BB00BB'>dot</font><font face='Lucida Console'>(</font>delta, g<font face='Lucida Console'>)</font> <font color='#5555FF'>&lt;</font> <font color='#979000'>0</font><font face='Lucida Console'>)</font>
            <font color='#0000FF'>return</font> p;
        <font color='#0000FF'>else</font>
            <font color='#0000FF'>return</font> vector<font color='#5555FF'>&lt;</font><font color='#0000FF'><u>double</u></font>,<font color='#979000'>2</font><font color='#5555FF'>&gt;</font><font face='Lucida Console'>(</font>p<font face='Lucida Console'>)</font><font color='#5555FF'>+</font><font color='#BB00BB'>clamp</font><font face='Lucida Console'>(</font>delta, <font color='#5555FF'>-</font><font color='#979000'>1</font>, <font color='#979000'>1</font><font face='Lucida Console'>)</font>;
    <b>}</b>

<font color='#009900'>// ----------------------------------------------------------------------------------------
</font>
<b>}</b>

<font color='#0000FF'>#endif</font> <font color='#009900'>// DLIB_MATRIx_LA_FUNCTS_
</font>


</pre></body></html>